home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 January: Mac OS SDK / Dev.CD Jan 98 SDK2.toast / Development Kits (Disc 2) / QuickTime™ VR 2.0 SDK / QTVR C⁄C++ Runtime API / Sample Code / VRShell Sample Code / VR3DSound / TestFunctions.c < prev    next >
Encoding:
Text File  |  1997-05-22  |  18.1 KB  |  695 lines  |  [TEXT/MPCC]

  1. //
  2. //    File:        TestFunctions.c
  3. //
  4. //    Contains:    Localized sound support for QuickTime VR movies.
  5. //
  6. //    Written by:    Tim Monroe
  7. //
  8. //    Copyright:    © 1996 by Apple Computer, Inc., all rights reserved.
  9. //
  10. //    Change History (most recent first):
  11. //
  12. //       <3>         01/24/97    rtm        major code overhaul: got orientation working correctly;
  13. //                                    moved most orientation processing to a prescreen routine;
  14. //                                    implemented listener/sources/channels/resources on a per-instance basis
  15. //       <2>         12/10/96    rtm        added VR3DSound_GetSoundHeader and VR3DSound_GetSndBaseFrequency
  16. //       <1>         12/09/96    rtm        ported earlier 3D sound support functions to VRShell
  17. //       
  18. //
  19. // ******************************************************************************
  20. // This file provides several functions to attach sounds to specific locations
  21. // in a panorama. As the viewer moves, the sounds should change their apparent position
  22. // accordingly. For example, if a sound is initially straight ahead of the viewer
  23. // and the viewer turns 90˚ right, the sound should then appear to come
  24. // from the viewer's left.
  25. //
  26. // Some of this code is straight out of the SoundSprocket documentation
  27. // (by yours truly!) or the SoundSprocket sample source (by Dan Venolia).
  28. //
  29. // The process of attaching a sound to a specific location might work like this:
  30. // (1) Create a hot spot of type 'snd ' in the panorama or object.
  31. // (2) Set the hot spot ID to be the 'snd ' resource ID of the sound for that location.
  32. // (3) Create a user data atom (or resource) that contains the distance of the sound source from the user.
  33. // This interface hasn't been implemented yet!!!
  34. // ******************************************************************************
  35. // TODO:
  36. // + this app reads the same sounds for all nodes and movies; fix that;
  37. //   we need a mechanism for a sound to indicate which movie/node it belongs to;
  38. // + figure out position of sound source from locations of sound hot spots, as described above
  39.  
  40.  
  41. // header files
  42. #include "TestFunctions.h"
  43. #include "MacFramework.h"
  44. #include "QTVRUtilities.h"
  45.  
  46.  
  47. // system headers
  48. #include <Windows.h>
  49. #include <Resources.h>
  50. #include <TextUtils.h>
  51. #include <fp.h>
  52. #include <CodeFragments.h>
  53.  
  54.  
  55. // global variables
  56. extern Boolean            gHasSoundSprockets;                    // is SoundSprockets available?
  57.  
  58. // local prototypes
  59. static Boolean            VR3DSound_CheckVersionNumber (const NumVersion *inVersion, UInt8 inMajor, UInt8 inMinor, UInt8 inBug);
  60. SoundHeaderPtr            VR3DSound_GetSoundHeader (Handle theSndHandle);
  61. long                    VR3DSound_GetSndBaseFrequency (Handle theSndHandle);
  62.  
  63.  
  64. //////////
  65. //
  66. // VR3DSound_CheckVersionNumber
  67. // Returns true if the given version number is compatible with
  68. // (that is, not older than) version inMajor.inMinor.inBug.
  69. //
  70. //////////
  71.  
  72. Boolean VR3DSound_CheckVersionNumber (
  73.     const NumVersion*        inVersion,
  74.     UInt8                    inMajor,
  75.     UInt8                    inMinor,
  76.     UInt8                    inBug)
  77. {
  78.     if (inVersion->majorRev != inMajor) {
  79.         return(inVersion->majorRev > inMajor);
  80.     } else {
  81.         return(inVersion->minorAndBugRev >= inMinor << 4 | inBug);
  82.     }
  83. }
  84.  
  85.  
  86. //////////
  87. //
  88. // VR3DSound_GetSoundHeader
  89. // Returns a pointer to the sound header in a sampled sound resource.
  90. //
  91. //////////
  92.  
  93. SoundHeaderPtr VR3DSound_GetSoundHeader (Handle theSndHandle)
  94. {
  95.     SoundHeaderPtr        mySndHeader = NULL;
  96.     long                myOffset = 0;
  97.     OSErr                myErr;
  98.     
  99.     myErr = GetSoundHeaderOffset((SndListHandle)theSndHandle, &myOffset);
  100.     if (myErr == noErr) {
  101.         mySndHeader = (SoundHeaderPtr)(*theSndHandle + myOffset);
  102.     }
  103.  
  104.     return(mySndHeader);
  105. }
  106.  
  107.  
  108. //////////
  109. //
  110. // VR3DSound_GetSndBaseFrequency
  111. // Returns the base frequency of a sampled sound.
  112. // We need this when installing the sound as a voice, in VR3DSound_PlayResource.
  113. //
  114. //////////
  115.  
  116. long VR3DSound_GetSndBaseFrequency (Handle theSndHandle)
  117. {
  118.     SoundHeaderPtr        mySndHeader;
  119.     long                myBaseFreq = 0;
  120.     
  121.     mySndHeader = VR3DSound_GetSoundHeader(theSndHandle);
  122.     if (mySndHeader != NULL) {
  123.         myBaseFreq = mySndHeader->baseFrequency;
  124.     }
  125.  
  126.     return(myBaseFreq);
  127. }
  128.  
  129.  
  130. //////////
  131. //
  132. // VR3DSound_Init
  133. // Initialize for 3D localized sound.
  134. //
  135. //////////
  136.  
  137. void VR3DSound_Init (void)
  138. {
  139.     NumVersion            myVersion;
  140.  
  141.     // check the Sound Manager version: we require version 3.2.1 or later
  142.     myVersion = SndSoundManagerVersion();
  143.     // ••• WARNING •••
  144.     // • IF YOU CAN'T COMPILE THE PREVIOUS LINE, YOU MUST UPGRADE TO ETO #20 OR
  145.     // • EDIT YOUR Sound.h TO MAKE SndSoundManagerVersion RETURN THE TYPE NumVersion.
  146.     
  147.     if (!VR3DSound_CheckVersionNumber(&myVersion, 3, 2, 1)) {
  148.         ShowWarning("\pIncorrect version of the Sound Manager; we need 3.2.1 or later.", 0);
  149.         ExitToShell();
  150.     }
  151.  
  152.     // now make sure that SoundSprockets is available;
  153.     // there is no Gestalt selector for this package, so we use an alternate strategy:
  154.     if ((short)SSpListener_New == kUnresolvedSymbolAddress) {
  155.         gHasSoundSprockets = false;
  156.         ShowWarning("\pSoundSprockets is not installed; cannot do localized sound.", 0);
  157.     } else {
  158.         gHasSoundSprockets = true;
  159.     }
  160.  
  161. }
  162.  
  163.  
  164. //////////
  165. //
  166. // VR3DSound_InitWindowData
  167. // Initialize window-specific data for 3D sound.
  168. //
  169. //////////
  170.  
  171. ApplicationDataHdl VR3DSound_InitWindowData (WindowObject theWindowObject)
  172. {
  173. #pragma unused(theWindowObject)
  174.  
  175.     OSStatus            myErr;
  176.     ApplicationDataHdl    myAppData;
  177.     
  178.     
  179.     myAppData = (ApplicationDataHdl)NewHandleClear(sizeof(ApplicationDataRecord));
  180.     if (myAppData != NULL) {
  181.  
  182.         // lock the application data handle
  183.         HLock((Handle)myAppData);
  184.         
  185.         // create a listener and set listener units to feet
  186.         myErr = SSpListener_New(&(**myAppData).fListener);
  187.         if (myErr == noErr) {
  188.             SSpListener_SetMetersPerUnit((**myAppData).fListener, 0.3048);
  189.         }
  190.  
  191.         // initialize other fields of application data structure
  192.         (**myAppData).fMustUpdateOrient = true;
  193.         
  194.         // unlock the application data handle
  195.         HUnlock((Handle)myAppData);
  196.     }
  197.     
  198.     return(myAppData);
  199. }
  200.  
  201.  
  202. //////////
  203. //
  204. // VR3DSound_CreateLocalizedChannel
  205. // Create a localized sound channel.
  206. //
  207. //////////
  208.  
  209. SndChannelPtr VR3DSound_CreateLocalizedChannel (void)
  210. {
  211.     SndChannelPtr        mySndChannel = nil;
  212.     OSStatus            myErr;
  213.     SoundComponentLink    myLink;
  214.     
  215.     // create a new sound channel
  216.     myErr = SndNewChannel(&mySndChannel, sampledSynth, initMono, nil);
  217.     if (myErr == noErr) {
  218.         
  219.         // install the 3D sound filters
  220.         myLink.description.componentType            = kSoundEffectsType;
  221.         myLink.description.componentSubType            = kSSpLocalizationSubType;
  222.         myLink.description.componentManufacturer    = 0;
  223.         myLink.description.componentFlags            = 0;        
  224.         myLink.description.componentFlagsMask        = 0;    
  225.         myLink.mixerID                                = nil;
  226.         myLink.linkID                                = nil;
  227.         
  228.         myErr = SndSetInfo(mySndChannel, siPreMixerSoundComponent, &myLink);
  229.         if (myErr != noErr) 
  230.             mySndChannel = nil;
  231.     }
  232.     
  233.     return(mySndChannel);
  234. }
  235.  
  236.  
  237. //////////
  238. //
  239. // VR3DSound_CreateLocalizedSource
  240. // Create a localized sound source.
  241. //
  242. //////////
  243.  
  244. SSpSourceReference VR3DSound_CreateLocalizedSource (void)
  245. {
  246.     SSpSourceReference        mySource = nil;
  247.     OSStatus                myErr;
  248.     
  249.     // create a new sound source
  250.     myErr = SSpSource_New(&mySource);
  251.     
  252.     return(mySource);
  253. }
  254.  
  255.  
  256. //////////
  257. //
  258. // VR3DSound_PlaySilence
  259. // Stop the sound playing from a particular source.
  260. //
  261. //////////
  262.  
  263. void VR3DSound_PlaySilence (WindowObject theWindowObject, short theChannelIndex)
  264. {
  265.     OSStatus            myErr;
  266.     SndCommand            mySndCommand;
  267.     ApplicationDataHdl    myAppData;
  268.  
  269.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  270.     if (myAppData == NULL)
  271.         return;
  272.     
  273.     if ((**myAppData).fChannels[theChannelIndex] == NULL)
  274.         return;
  275.         
  276.     mySndCommand.cmd = quietCmd;
  277.     mySndCommand.param1 = 0;
  278.     mySndCommand.param2 = 0;
  279.     myErr = SndDoImmediate((**myAppData).fChannels[theChannelIndex], &mySndCommand);
  280. }
  281.  
  282.  
  283. //////////
  284. //
  285. // VR3DSound_PlayResource
  286. // Play the snd resource of the given ID on a particular channel.
  287. // Currently, we just loop the sound indefinitely. We should provide
  288. // more options (via a parameter flag) for sound duration, repetition, etc.
  289. //
  290. //////////
  291.  
  292. void VR3DSound_PlayResource (WindowObject theWindowObject, short theChannelIndex, short theResID)
  293. {
  294.     OSStatus            myErr;
  295.     SndCommand            mySndCommand;
  296.     long                myOffset;
  297.     ApplicationDataHdl    myAppData;
  298.  
  299.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  300.     if (myAppData == NULL)
  301.         return;
  302.  
  303.     // lock the application data handle
  304.     HLock((Handle)myAppData);
  305.     
  306.     // silence the sound channel
  307.     VR3DSound_PlaySilence(theWindowObject, theChannelIndex);
  308.     
  309.     // get the resource
  310.     (**myAppData).fResources[theChannelIndex] = (SndListHandle)GetResource('snd ', theResID);
  311.     if ((**myAppData).fResources[theChannelIndex] == NULL || ResError() != noErr) {
  312.         return;
  313.     }
  314.     
  315.     // lock the resource data down
  316.     HLockHi((Handle)(**myAppData).fResources[theChannelIndex]);
  317.     
  318.     // play the sound indefinitely
  319.     GetSoundHeaderOffset((**myAppData).fResources[theChannelIndex], &myOffset);
  320.     
  321.     mySndCommand.cmd = soundCmd;
  322.     mySndCommand.param1 = 0;
  323.     mySndCommand.param2 = (long)*((**myAppData).fResources[theChannelIndex]) + myOffset;
  324.     myErr = SndDoImmediate((**myAppData).fChannels[theChannelIndex], &mySndCommand);
  325.  
  326.     mySndCommand.cmd = freqCmd;
  327.     mySndCommand.param1 = 0;
  328.     mySndCommand.param2 = VR3DSound_GetSndBaseFrequency((Handle)(**myAppData).fResources[theChannelIndex]);
  329.     myErr = SndDoImmediate((**myAppData).fChannels[theChannelIndex], &mySndCommand);
  330.  
  331.     // unlock the application data handle
  332.     HUnlock((Handle)myAppData);
  333. }
  334.  
  335.  
  336. //////////
  337. //
  338. // VR3DSound_CountSoundHotSpotsInNode
  339. // Determine how many sound source hot spots are in the current node.
  340. //
  341. //////////NOT FULLY IMPLEMENTED!!!!
  342.  
  343. UInt32 VR3DSound_CountSoundHotSpotsInNode (WindowObject theWindowObject)
  344. {
  345.     OSStatus            myErr = noErr;
  346.     QTAtomContainer        myNodeInfo;
  347.     QTAtom                myHotSpotParentAtom;
  348.     short                 myHotSpotCount = 0;
  349.     QTVRInstance        myInstance;
  350.     
  351.     return(kMaxNumSourcesPerNode);            //just cheating, for now!
  352.  
  353.     if (theWindowObject == NULL)
  354.         return(0);
  355.         
  356.     myInstance = (**theWindowObject).fInstance;
  357.     
  358.     // get the node information atom container
  359.     myErr = QTVRGetNodeInfo(myInstance, kQTVRCurrentNode, &myNodeInfo);
  360.     
  361.     // get the hot spot parent atom
  362.     if (!myErr)
  363.         myHotSpotParentAtom = QTFindChildByID(myNodeInfo, kParentAtomIsContainer, kQTVRHotSpotParentAtomType, 1, nil);
  364.         
  365.     // get the number of hot spot atoms in that parent
  366.     if (myHotSpotParentAtom != 0) {
  367.         myHotSpotCount = QTCountChildrenOfType(myNodeInfo, myHotSpotParentAtom, kQTVRHotSpotAtomType);
  368.     }    
  369.         
  370.     if (myHotSpotCount > kMaxNumSourcesPerNode)
  371.         myHotSpotCount = kMaxNumSourcesPerNode;
  372.  
  373.     return((UInt32)myHotSpotCount);
  374. }
  375.  
  376.  
  377. //////////
  378. //
  379. // VR3DSound_Update3DSoundEnv
  380. // Update the virtual audio environment.
  381. //
  382. //////////
  383.  
  384. void VR3DSound_Update3DSoundEnv (WindowObject theWindowObject)
  385. {
  386.     short                    myIndex;
  387.     UInt32                    myCount;
  388.     SSpLocalizationData        myData;
  389.     ApplicationDataHdl        myAppData;
  390.  
  391.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  392.     if (myAppData == NULL)
  393.         return;
  394.     
  395.     myCount = VR3DSound_CountSoundHotSpotsInNode(theWindowObject);
  396.  
  397.     // update the virtual audio environment
  398.     for (myIndex = 0; myIndex < myCount; myIndex++) {
  399.         SSpSource_CalcLocalization((**myAppData).fSources[myIndex], (**myAppData).fListener, &myData);
  400.         SndSetInfo((**myAppData).fChannels[myIndex], siSSpLocalization, &myData);
  401.     }
  402. }
  403.  
  404.  
  405. //////////
  406. //
  407. // VR3DSound_StartNodeSounds
  408. // Start playing all sounds for the current node.
  409. //
  410. //////////
  411.  
  412. void VR3DSound_StartNodeSounds (WindowObject theWindowObject)
  413. {
  414.     UInt32                    myCount;
  415.     short                    myIndex;
  416.     //SSpLocationData         theLoc;
  417.     TQ3Point3D                myPoint;
  418.     TQ3Vector3D                myOrient;
  419.     ApplicationDataHdl        myAppData;
  420.  
  421.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  422.     if (myAppData == NULL)
  423.         return;
  424.     
  425.     // right now, just brute-force the locations
  426.     myCount = VR3DSound_CountSoundHotSpotsInNode(theWindowObject);
  427.  
  428.     for (myIndex = 0; myIndex < myCount; myIndex++) {
  429.         (**myAppData).fSources[myIndex] = VR3DSound_CreateLocalizedSource();
  430.         (**myAppData).fChannels[myIndex] = VR3DSound_CreateLocalizedChannel();
  431.         switch (myIndex) {
  432.             case 0:
  433.                 myPoint.x = kObjectDistance;
  434.                 myPoint.y = 0.0;
  435.                 myPoint.z = 0.0;
  436.                 myOrient.x = -kObjectDistance;
  437.                 myOrient.y = 0.0;
  438.                 myOrient.z = 0.0;
  439.                 break;
  440.             case 1:
  441.                 myPoint.x = 0.0;
  442.                 myPoint.y = 0.0;
  443.                 myPoint.z = kObjectDistance;
  444.                 myOrient.x = 0.0;
  445.                 myOrient.y = 0.0;
  446.                 myOrient.z = -kObjectDistance;
  447.                 break;
  448.             case 2:
  449.                 myPoint.x = 0.0;
  450.                 myPoint.y = 0.0;
  451.                 myPoint.z = -kObjectDistance;
  452.                 myOrient.x = 0.0;
  453.                 myOrient.y = 0.0;
  454.                 myOrient.z = kObjectDistance;
  455.                 break;
  456.             case 3:
  457.                 myPoint.x = -kObjectDistance;
  458.                 myPoint.y = 0.0;
  459.                 myPoint.z = 0.0;
  460.                 myOrient.x = kObjectDistance;
  461.                 myOrient.y = 0.0;
  462.                 myOrient.z = 0.0;
  463.                 break;
  464.         }
  465.                 
  466.         SSpSource_SetPosition((**myAppData).fSources[myIndex], &myPoint);
  467.         SSpSource_SetOrientation((**myAppData).fSources[myIndex], &myOrient);
  468.         SSpSource_SetAngularAttenuation((**myAppData).fSources[myIndex], kVRPi/8, 20.0);
  469.         
  470.         VR3DSound_Update3DSoundEnv(theWindowObject);
  471.         VR3DSound_PlayResource(theWindowObject, myIndex, 128 + myIndex);    
  472.     }
  473. }
  474.  
  475.  
  476. //////////
  477. //
  478. // VR3DSound_StopNodeSounds
  479. // Stop playing all sounds for the specified node.
  480. //
  481. //////////
  482.  
  483. void VR3DSound_StopNodeSounds (WindowObject theWindowObject)
  484. {
  485.     short            myIndex;
  486.     UInt32            myCount;
  487.     
  488.     // get the number of sound source hot spots in this node
  489.     myCount = VR3DSound_CountSoundHotSpotsInNode(theWindowObject);
  490.     
  491.     // stop playing any localized sounds associated with this node
  492.     for (myIndex = 0; myIndex < myCount; myIndex++) {
  493.         VR3DSound_PlaySilence(theWindowObject, myIndex);
  494.     }
  495. }
  496.  
  497.  
  498. //////////
  499. //
  500. // VR3DSound_DumpNodeSounds
  501. // Release all sound resources for the specified node.
  502. //
  503. //////////
  504.  
  505. void VR3DSound_DumpNodeSounds (WindowObject theWindowObject)
  506. {
  507.     short                    myIndex;
  508.     UInt32                    myCount;
  509.     ApplicationDataHdl        myAppData;
  510.  
  511.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  512.     if (myAppData == NULL)
  513.         return;
  514.     
  515.     // get the number of sound source hot spots in this node
  516.     myCount = VR3DSound_CountSoundHotSpotsInNode(theWindowObject);
  517.     
  518.     // get rid of associated resources
  519.     for (myIndex = 0; myIndex < myCount; myIndex++) {
  520.         if ((**myAppData).fResources[myIndex] != NULL)
  521.             ReleaseResource((Handle)(**myAppData).fResources[myIndex]);
  522.     }
  523. }
  524.  
  525.  
  526. //////////
  527. //
  528. // VR3DSound_InstallPrescreenRoutine
  529. // Install a prescreen buffer imaging complete procedure
  530. // to alter the position of the listener based on the user's panning or tilting.
  531. //
  532. //////////
  533.  
  534. void VR3DSound_InstallPrescreenRoutine (QTVRInstance theInstance, WindowObject theWindowObject)
  535. {
  536.     ImagingCompleteUPP    myImagingProc;
  537.  
  538.     myImagingProc = NewImagingCompleteProc(VR3DSound_PrescreenRoutine);    
  539.     QTVRSetPrescreenImagingCompleteProc(theInstance, myImagingProc, (SInt32)theWindowObject, 0);
  540.  
  541.     // we want our prescreen imaging procedure to be called *every* time a QTVR image is drawn,
  542.     // so we must turn off direct screen drawing for all drawing modes (both motion and static)
  543.     QTVRSetImagingProperty(theInstance, kQTVRAllModes, kQTVRImagingDirectDraw, 0);
  544. }
  545.  
  546.  
  547. //////////
  548. //
  549. // VR3DSound_InstallInterceptRoutine
  550. // Install a QTVR intercept procedure to signal that the listener orientation
  551. // needs to be updated.
  552. //
  553. //////////
  554.  
  555. void VR3DSound_InstallInterceptRoutine (QTVRInstance theInstance, WindowObject theWindowObject)
  556. {
  557.     QTVRInterceptUPP    myInterceptProc;
  558.     
  559.     myInterceptProc = NewQTVRInterceptProc(VR3DSound_InterceptRoutine);    
  560.     
  561.     // we'll just use the same intercept proc for each intercepted procedure
  562.     QTVRInstallInterceptProc(theInstance, kQTVRSetPanAngleSelector, myInterceptProc, (SInt32)theWindowObject, 0);
  563.     QTVRInstallInterceptProc(theInstance, kQTVRSetTiltAngleSelector, myInterceptProc, (SInt32)theWindowObject, 0);
  564. }
  565.  
  566.  
  567. ///////////
  568. //
  569. // VR3DSound_PrescreenRoutine
  570. // Alter the position of the listener based on the user's panning or tilting.
  571. //
  572. //////////
  573.  
  574. pascal OSErr VR3DSound_PrescreenRoutine (QTVRInstance theInstance, WindowObject theWindowObject)
  575. {
  576.     float                myPan;
  577.     float                myTilt;
  578.     TQ3Vector3D            myOrientation;
  579.     ApplicationDataHdl    myAppData;
  580.  
  581.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  582.     if (myAppData == NULL)
  583.         return(paramErr);
  584.         
  585.     if (!(**myAppData).fMustUpdateOrient)
  586.         return(noErr);
  587.     
  588.     // get the current pan and tilt angles (in radians)
  589.     myPan = QTVRGetPanAngle(theInstance);
  590.     myTilt = QTVRGetTiltAngle(theInstance);
  591.     
  592.     // figure out the orientation    
  593.     myOrientation.x = -sin(myPan) * cos(myTilt);
  594.     myOrientation.y = sin(myTilt);
  595.     myOrientation.z = -cos(myPan) * cos(myTilt);
  596.         
  597.     // set the new orientation of the listener
  598.     SSpListener_SetOrientation((**myAppData).fListener, &myOrientation);
  599.     
  600.     // update the virtual audio environment
  601.     VR3DSound_Update3DSoundEnv(theWindowObject);
  602.     
  603.     // clear the update flag
  604.     (**myAppData).fMustUpdateOrient = false;
  605.         
  606.     return(noErr);
  607. }
  608.  
  609.  
  610. //////////
  611. //
  612. // VR3DSound_InterceptRoutine
  613. // signal that the listener orientation needs to be updated.
  614. //
  615. //////////
  616.  
  617. pascal void VR3DSound_InterceptRoutine (QTVRInstance theInstance, QTVRInterceptPtr theMsg, WindowObject theWindowObject, Boolean *cancel)
  618. {
  619. #pragma unused(theInstance)
  620.  
  621.     Boolean                myCancelInterceptedProc = false;    // true == do NOT call thru; false == call thru
  622.     ApplicationDataHdl    myAppData;
  623.  
  624.     myAppData = (ApplicationDataHdl)GetAppDataFromWindowObject(theWindowObject);
  625.     if (myAppData == NULL)
  626.         return;
  627.         
  628.     switch (theMsg->selector) {
  629.         case kQTVRSetPanAngleSelector:
  630.         case kQTVRSetTiltAngleSelector:
  631.             (**myAppData).fMustUpdateOrient = true;
  632.             break;
  633.             
  634.         default:
  635.             break;
  636.     }
  637.     
  638.     *cancel = myCancelInterceptedProc;
  639. }
  640.  
  641.  
  642. //////////
  643. //
  644. // VR3DSound_EnteringNodeProc
  645. // A node-entering procedure: start any sounds attached to the new node.
  646. //
  647. //////////
  648.  
  649. pascal OSErr VR3DSound_EnteringNodeProc (QTVRInstance theInstance, long nodeID, WindowObject theWindowObject)
  650. {
  651. #pragma unused(theInstance, nodeID)
  652.  
  653.     if (theWindowObject == NULL)
  654.         return(paramErr);
  655.         
  656.     VR3DSound_StartNodeSounds(theWindowObject);
  657.     
  658.     return(noErr);
  659. }
  660.  
  661.  
  662. //////////
  663. //
  664. // VR3DSound_LeavingNodeProc
  665. // A node-leaving procedure: stop any sounds attached to the current node.
  666. //
  667. //////////
  668.  
  669. pascal OSErr VR3DSound_LeavingNodeProc (QTVRInstance theInstance, long fromNodeID, long toNodeID, Boolean *cancel, WindowObject theWindowObject)
  670. {
  671. #pragma unused(theInstance, fromNodeID, toNodeID, cancel)
  672.  
  673.     if (theWindowObject == NULL)
  674.         return(paramErr);
  675.         
  676.     VR3DSound_StopNodeSounds(theWindowObject);
  677.     VR3DSound_DumpNodeSounds(theWindowObject);    
  678.     
  679.     return(noErr);
  680. }
  681.  
  682.  
  683. //////////
  684. //
  685. // MyTestFunc
  686. //
  687. //////////
  688.  
  689. void MyTestFunc (QTVRInstance theInstance)
  690. {
  691.     QTVRSetPanAngle(theInstance, 0.0);
  692.     QTVRSetTiltAngle(theInstance, 0.0);
  693.     QTVRUpdate(theInstance, kQTVRStatic);    
  694. }
  695.